package com.cskaoyan.javase.oop1._1basic;

import com.sun.xml.internal.ws.addressing.v200408.MemberSubmissionWsaClientTube;

/**
 * 对象的创建和使用
 * 这里给出一个案例：
 * 创建学生对象，然后使用访问学生对象的属性，使用学生对象的行为。
 *
 * 要想创建对象,首先需要创建对象的模板,也就是class,所以需要首先定义学生类
 * 类的定义:
 * 语法:
 * [各种修饰符] class 类名{
 *     // 类体
 * }
 * 注:
 *      1.能够修饰类class的修饰符有很多,主要包括访问权限修饰符,final等
 *          在这里我们只需要记住
 *          public 可以修饰class
 *          还有就可以不写任何修饰符,是一个非public修饰的class
 *      2.一个Java文件下,所有的class都是同包的关系,而同包下不允许存在同名类
 *      3.特别声明: 在日常开发中
 *          我们绝大多数都会定义public class 极少定义非public class
 *          但是为了课堂演示方便,我们在课堂上,会优先定义非public class
 *          然后把public class Demo作为一个测试类 进行演示
 *      4.类名要遵循大驼峰式的命名规范,并且要见名知意.
 *      5.特别强调:
 *              类的定义位置
 *              正常情况下,两个类如果定义在同一个java文件下,是相互独立的
 *              但是Java中的类是可以嵌套定义的,称之为内部类
 *              但是目前大家的学习进度,不要定义内部类,内部类的语法你不会,定义内部类会导致错误
 *              一定要看清楚,类体的大括号,不要定义内部类
 *
 * 学生类定义完毕后,开始定义学生类中的结构
 * 类是模板,抽取了该类型全体对象的属性和行为上的共性,用于描述全体对象,作为创建对象的模板
 * 类是怎么描述属性的共性呢?
 * 类中使用成员变量(member variable)来描述全体对象属性上的共性.
 * 什么是成员变量?成员变量如何定义?
 *      局部变量: 指的是定义在方法或者一个作用域内部的变量,是定义在局部位置的一个变量.
 *      成员变量: 指的是定义在成员位置的一个变量.
 *          成员位置: 类体中,局部位置以外的其他位置都是成员位置
 *      成员变量的定义语法:
 *          [各种修饰符] 数据类型 成员变量名;
 *          注: 目前大家没有学习修饰符,可以先省略不写.
 *
 * 类中使用成员方法(member method)来描述全体对象行为上的共性
 * 什么是成员方法?怎么定义成员方法呢?
 * 成员方法: 定义在成员位置的,并且没有static修饰的一个方法,就是成员方法
 * 定义语法:
 * [访问权限修饰符] 返回值类型 方法名(形参列表){
 *     // 方法体
 * }
 * 访问权限修饰符没有学习,这里默认是public
 * 注: 成员变量名,成员方法名都是要小驼峰式书写的
 *
 * 以上成员变量和成员方法定义完毕后,这个类就定义完毕了
 * 于是创建类的模板就定义完毕了,我们开始创建对象,使用对象.
 *
 * 创建对象的位置:
 *      普遍来说,应该在一个方法中创建对象(当然其它位置也不是不行)
 *
 * 创建对象需要的前提:
 *      必须要具有这个类的访问权限,才能创建这个类的对象
 *
 * 创建对象的语法:
 *      类名 对象名 = new 类名();
 *
 * 对象创建完毕后,就可以使用对象来访问成员变量,调用成员方法(无论是成员变量还是成员方法都是属于对象的,都必须创建对象才能使用)
 *
 * 成员变量的访问语法: 对象名点成员变量名
 *      对象当中的成员变量,类似于数组中的元素
 *      它的取值具有默认初始化的步骤,具有默认值
 *      而且默认值是永远的第一步,不可省略
 *
 * 成员方法的调用语法: 对象名点成员方法名(实参);
 *      成员方法也是属于对象的,必须创建对象后才能够调用成员方法
 *
 * 成员方法中,是可以去访问自身类的成员变量的,对象名点成员变量可以获取该成员变量的取值,也可以用于成员变量的赋值.
 *
 * 最后,我们直接打印对象名,查看直接打印引用的结果,和打印数组是类似的,默认情况下会显式对象的地址值
 * com.cskaoyan.javase.oop1._1basic.Student@1540e19d
 * 首先是全限定类名 + "@" + 十六进制地址值
 * 注: 默认情况下,打印对象名是打印地址值,但是这个打印结果是可以修改的.
 *
 *
 * @since 11:11
 * @author wuguidong@cskaoyan.onaliyun.com
 */
public class Demo {

    // 成员位置
    public static void main(String[] args) {
        // 创建Student对象
        Student s = new Student();
        // null
        System.out.println(s.name);
        // 0
        System.out.println(s.age);
        // 0
        System.out.println(s.id);

        s.study();
        s.sleep();
        System.out.println(s.eat(10));

        System.out.println("---------------------");
        s.name = "张三";
        System.out.println(s.name);
        s.study();
        System.out.println("------------------------");
        System.out.println(s);

        Student s2 = new Student();

        // 这里返回false,因为它们两个引用指向的不是同一个对象
        System.out.println(s == s2);
    }

    // 成员位置
    public static void test() {
    }
}

// 定义学生类
class Student {
    // 抽取全体学生对象属性的共性 得到成员变量
    // 定义在成员位置
    // 属性的共性: 名字.年龄,学号
    String name;
    int age;
    int id;

    // 抽取全体学生对象行为的共性,得到成员方法
    // 定义在成员位置,没有static修饰
    // 行为的共性: 学习,吃饭,睡觉
    public void study() {
        System.out.println(name + "好好学习天天向上!");
    }

    public int eat(int a) {
        System.out.println("我想吃饭");
        return 0;
    }

    public void sleep() {
        System.out.println("我正在睡觉!");
    }
}